Callbacks in JavaScript
callbacks are functions passed as arguments to other functions and are executed after some operation has been completed. Callbacks are a foundational concept in asynchronous programming and event-driven design. This enables a higher level of abstraction and flexibility in programming. In this article, we will explore the concept of callbacks in JavaScript, their types, and how to use them effectively.
Why Use Callbacks?
JavaScript is single-threaded, meaning it executes one operation at a time. Callbacks help manage:
Asynchronous operations (e.g., reading a file, fetching data from an API)
Event handling (e.g., user clicks, form submissions)
Synchronous vs Asynchronous in JavaScript
What is Synchronous?
Synchronous operations are executed one after the other. The next task waits for the current one to finish.
console.log("Start");
console.log("Processing...");
console.log("End");
Output:-
Start
Processing...
End
What is Asynchronous?
Asynchronous operations don’t block the execution. The task is started, and JavaScript moves on to the next task without waiting for the current one to finish.
console.log("Start");
setTimeout(() => {
console.log("Async Task");
}, 2000);
console.log("End");
Output:-
Scenario: Ordering a Pizza
You call a pizza shop and place an order. You don’t just sit there waiting until the pizza arrives — instead, you give them your phone number and say:
“Call me when the pizza is ready.”
function orderPizza(callback) {
console.log("Ordering pizza...");
setTimeout(() => {
console.log("Pizza is ready!");
callback(); // This is like the pizza shop calling you back
}, 2000);
}
function eatPizza() {
console.log("Eating the pizza");
}
orderPizza(eatPizza);
Output:-
Ordering pizza...
(pause for 2 seconds)
Pizza is ready!
Eating the pizza
What Happened Here?
You ordered a pizza (called orderPizza()).
You passed eatPizza as a callback — like giving your number.
When the pizza is ready (setTimeout simulates the delay), the shop calls you back by running callback() (i.e., eatPizza()).
You get notified and eat the pizza .
Error Handling in Callbacks
// Function that simulates ordering a pizza
function orderPizza(flavor, callback) {
console.log(`Ordering ${flavor} pizza...`);
setTimeout(() => {
// Simulate an error if the flavor is pineapple
if (flavor === "pineapple") {
callback("Sorry, we don't serve pineapple pizza.", null);
} else {
// No error, return the pizza
callback(null, `Here's your ${flavor} pizza!`);
}
}, 1000);
}
// Callback function to handle the result or error
function handlePizza(error, pizza) {
if (error) {
console.log("Error:", error);
} else {
console.log("Success:", pizza);
}
}
// Call the function with a valid pizza flavor
orderPizza("pepperoni", handlePizza);
// Call the function with an invalid flavor to trigger an error
orderPizza("pineapple", handlePizza);
Output:-
Ordering pepperoni pizza...
Ordering pineapple pizza...
// after 1 second...
Success: Here's your pepperoni pizza!
Error: Sorry, we don't serve pineapple pizza.
Note:- This code simulates ordering pizza asynchronously using callbacks. The orderPizza function logs the order and waits 1 second using setTimeout. If the flavor is "pineapple", it returns an error via the callback; otherwise, it returns a success message. The handlePizza function handles both success and error messages based on what it receives.
Further Reading:
MDN: Callback Functions
Promises in JavaScript – Beginner Guide
Understanding Async/Await